﻿using System;
using System.ComponentModel;
using System.Windows;

namespace MVVM.ViewModel {
    public abstract class ViewModel:INotifyPropertyChanged,IDisposable {

        INavigationActions navigator;
        object context;

        public ViewModel() {
            navigator = Application.Current as INavigationActions;
            if (navigator != null) {
                navigator.PropertyChanged += application_PropertyChanged;
            }
        }

        void application_PropertyChanged(object sender, PropertyChangedEventArgs e) {
            if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "View")
                OnPropertyChanged("View");
        }

        public INavigationActions NavigationActions {
            get {
                return navigator;
            }
            set {
                if (navigator != value) {
                    SetAction(value);
                    OnPropertyChanged("NavigationActions");
                }
            }
        }

        protected virtual void SetAction(INavigationActions value) {
            if (navigator != null)
                navigator.PropertyChanged -= application_PropertyChanged;
            navigator = value;
            if (navigator != null)
                navigator.PropertyChanged += application_PropertyChanged;
        }

        #region INotifyPropertyChanged Members
        /// <summary>
        /// Raised when a property has a new value
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// Raise the event
        /// </summary>
        /// <param name="propertyName">Property name that has new value</param>
        protected virtual void OnPropertyChanged(string propertyName) {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null) {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
        #endregion

        #region IDisposable Members
        /// <summary>
        /// Implementation of the dispose method
        /// </summary>
        public void Dispose() {
            this.OnDispose();
        }
        /// <summary>
        /// The child class should implement a personal dispose procedure
        /// </summary>
        protected virtual void OnDispose() {
            //do nothing because abstract
        }

        #endregion
    }
}
